<template>
  <view class="app">
    <!-- 头部 -->
    <view class="header">
      <!-- 地址 -->
      <view></view>

      <view class="header-btn" @click="setCart()">
        <text v-show="!isEdit">管理</text>
        <text v-show="isEdit">完成</text>
      </view>
    </view>

    <!-- 中部 -->
    <view class="main">
      <z-paging
        ref="paging"
        class="list"
        v-model="cartList"
        :default-page-size="limit"
        :to-bottom-loading-more-enabled="true"
        :auto="true"
        :fixed="false"
        :show-scrollbar="false"
        :show-loading-more-no-more-view="false"
        :refresher-enabled="true"
        @query="getData"
      >
        <view class="goods-item" v-for="(item, index) in cartList" :key="index">
          <view class="item-left">
            <u-checkbox
              active-color="orange"
              shape="circle"
              @change="selectGoods($event, item.id)"
              size="40"
              v-model="item.selected"
            ></u-checkbox>
            <view class="goods-logo" @click="goto(item.goods_id)">
              <image :src="item.goods.goods_logo"></image>
            </view>
          </view>
          <view class="item-right">
            <view class="goods-name">{{ item.goods.goods_name }}</view>
            <text class="desc-box" v-if="item.goods.goods_desc">
              <text class="goods-desc line-2">{{ item.goods.goods_desc }}</text>
            </text>
            <view class="goods-bottom">
              <text class="goods-price">{{ item.goods.goods_specs[0].goods_price }}</text>
              <view class="num-box">
                <view class="minus-btn" @click.stop="minusNum(item)">
                  <u-icon name="minus" size="23" :color="item.num_minus ? 'black' : 'lightgray'"></u-icon>
                </view>
                <input
                  class="goods-num"
                  type="number"
                  v-model.number="item.goods_num"
                  @blur="checkNum(item)"
                  maxlength="3"
                />
                <view class="plus-btn" @click.stop="plusNum(item)">
                  <u-icon name="plus" size="23" :color="item.num_plus ? 'black' : 'lightgray'"></u-icon>
                </view>
              </view>
            </view>
          </view>
        </view>
      </z-paging>
    </view>

    <!-- 尾部 -->
    <view class="footer flex" v-show="!isEdit">
      <view class="footer-left">
        <u-checkbox
          active-color="orange"
          shape="circle"
          @change="changeAllSelected"
          size="38"
          v-model="allSelected"
        ></u-checkbox>
        <text class="ml-20rpx">全选</text>
        <view class="total">
          <text>合计:</text>
          <text class="goods-price">{{ amount }}</text>
          <text class="total-num">(共{{ cartStore.buySelect.length }}件)</text>
        </view>
      </view>
      <text class="action-btn settle" @click="buyGoods()">结算</text>
    </view>

    <view class="footer flex" v-show="isEdit">
      <view class="footer-left">
        <u-checkbox
          active-color="orange"
          shape="circle"
          @change="changeAllSelected"
          size="38"
          v-model="allSelected"
        ></u-checkbox>
        <text class="ml-20rpx">全选</text>
        <view class="total">
          <text>已选{{ cartStore.delSelect.length }}件</text>
        </view>
      </view>
      <text class="action-btn delete" @click="delGoods()">删除</text>
    </view>
  </view>
</template>

<script lang="ts" setup>
  import { ref, computed, nextTick } from 'vue';
  import { report } from '@/utils/exception';
  import { getGoodsCart as getDataApi, setGoodsCart, delGoodsCart } from '@/api/goods/cart';
  import { useCartStore } from '@/store/cart';
  import { onShow } from '@dcloudio/uni-app';
  import calc from '@/utils/math';
  import { msg } from '@/utils/msg';
  import type { GoodsCartItem } from '@/types/cart';

  const isEdit = ref<boolean>(false);
  const selectType = ref<string>('buySelect');
  const limit = 10;
  const paging = ref();
  const cartList = ref<GoodsCartItem[]>([]);
  const cartStore = useCartStore();

  const getData = (pageNo: number, pageSize: number) => {
    getDataApi(pageNo, pageSize)
      .then((res) => {
        res.data.list.forEach((item: GoodsCartItem) => {
          item.selected = cartStore[selectType.value].includes(item.id);
          item.old_num = item.goods_num;
          item.old_specs_id = item.goods_specs_id;
          initNum(item);
        });
        paging.value.complete(res.data.list);

        // 成功下订单后，更新购物车已选择的商品
        if (cartStore.cartReload == 2) {
          let allCartIds = res.data.list.map((item: GoodsCartItem) => item.id);
          let newBuySelect: number[] = [];
          let newDelSelect: number[] = [];
          cartStore.buySelect.forEach((cartId) => {
            if (allCartIds.includes(cartId)) {
              newBuySelect.push(cartId);
            }
          });
          cartStore.buySelect = newBuySelect;

          cartStore.delSelect.forEach((cartId) => {
            if (allCartIds.includes(cartId)) {
              newDelSelect.push(cartId);
            }
          });
          cartStore.delSelect = newDelSelect;
        }
        cartStore.cartReload = 0;
      })
      .catch((err) => {
        report(err);
      });
  };

  const setCart = () => {
    isEdit.value = !isEdit.value;

    if (!isEdit.value) {
      selectType.value = 'buySelect';
      cartList.value.forEach((item: GoodsCartItem) => {
        item.selected = cartStore.buySelect.includes(item.id);
      });
      cartStore.delSelect = [];
    } else {
      selectType.value = 'delSelect';
      cartList.value.forEach((item: GoodsCartItem) => {
        item.selected = false;
      });
    }
  };

  const initNum = (cartItem: GoodsCartItem) => {
    if (cartItem.goods.goods_specs[0].goods_stock <= 0) {
      cartItem.num_minus = false;
      cartItem.num_plus = false;
      return;
    }
    checkNum(cartItem);
  };

  const checkNum = (cartItem: GoodsCartItem) => {
    if (cartItem.goods_num < cartItem.goods.goods_specs[0].goods_stock) {
      cartItem.num_plus = true;
      if (cartItem.goods_num >= 999) {
        cartItem.goods_num = 999;
        cartItem.num_plus = false;
      }
    } else {
      cartItem.goods_num = cartItem.goods.goods_specs[0].goods_stock;
      cartItem.num_plus = false;
    }

    if (cartItem.goods_num > 1) {
      cartItem.num_minus = true;
    } else {
      cartItem.goods_num = 1;
      cartItem.num_minus = false;
    }

    if (cartItem.goods_num != cartItem.old_num || cartItem.goods_specs_id != cartItem.old_specs_id) {
      setGoodsCart(cartItem.id, cartItem.goods_specs_id, cartItem.goods_num)
        .then((res) => {
          cartItem.old_num = cartItem.goods_num;
          cartItem.old_specs_id = cartItem.goods_specs_id;
        })
        .catch((err) => {
          report(err);
        });
    }
  };

  let timer: any;
  const minusNum = (cartItem: GoodsCartItem) => {
    if (!cartItem.num_minus) return;
    clearTimeout(timer);
    timer = setTimeout(() => {
      cartItem.goods_num--;
      checkNum(cartItem);
    }, 100);
  };

  const plusNum = (cartItem: GoodsCartItem) => {
    if (!cartItem.num_plus) return;
    clearTimeout(timer);
    timer = setTimeout(() => {
      cartItem.goods_num++;
      checkNum(cartItem);
    }, 100);
  };

  // 勾选商品
  const selectGoods = (e: any, cartId: number) => {
    if (e.value) {
      cartStore[selectType.value].push(cartId);
    } else {
      const index = (cartStore[selectType.value] as number[]).findIndex((item) => item == cartId);
      if (index != -1) {
        cartStore[selectType.value].splice(index, 1);
      }
    }
  };

  // 全选
  const changeAllSelected = (e: any) => {
    if (e.value) {
      // 全选
      cartList.value.forEach((item) => {
        if (!item.selected) {
          item.selected = true;
          cartStore[selectType.value].push(item.id);
        }
      });
    } else {
      // 全不选
      cartList.value.forEach((item, index) => {
        if (item.selected) {
          item.selected = false;
        }
      });
      cartStore[selectType.value] = [];
    }
  };

  // 合计件数
  const allSelected = computed(() => {
    if (cartList.value.length == 0) {
      return false;
    } else {
      return cartList.value.length == cartStore[selectType.value].length;
    }
  });

  // 合计金额
  const amount = computed(() => {
    return cartList.value.reduce((prev: number, next: GoodsCartItem) => {
      return next.selected
        ? calc.add(prev, calc.mul(next.goods_num, parseFloat(next.goods.goods_specs[0].goods_price)))
        : prev;
    }, 0);
  });

  // 结算
  const buyGoods = () => {
    if (cartStore.buySelect.length == 0) {
      return msg.error('请选择商品');
    }

    let orderGoods = '';
    cartList.value.forEach((item) => {
      if (item.selected) {
        if (orderGoods) orderGoods += '|';
        orderGoods += `${item.goods_id}@${item.goods_specs_id}@${item.goods_num}`;
      }
    });

    const cartIds = cartStore.buySelect.join(',');
    uni.navigateTo({ url: `/pages/order/pay?order_goods=${orderGoods}&cart_ids=${cartIds}` });
  };

  // 删除
  const delGoods = () => {
    if (cartStore.delSelect.length == 0) {
      return msg.error('请选择商品');
    }

    const delNum = cartStore.delSelect.length;
    msg.confirm(`确定删除所选的${delNum}个商品？`, () => {
      delGoodsCart(cartStore.delSelect)
        .then((res) => {
          msg.success('删除成功');
          cartStore.buySelect = cartStore.buySelect.filter((item) => !cartStore.delSelect.includes(item));
          cartStore.delSelect = [];
          const leftCartNum = cartStore.cartNum - delNum;
          cartStore.cartNum = leftCartNum <= 0 ? 0 : leftCartNum;
          paging.value.reload();
        })
        .catch((err) => {
          report(err);
        });
    });
  };

  const goto = (id: number) => {
    uni.navigateTo({ url: `/pages/goods/detail?id=${id}` });
  };

  onShow(() => {
    if (cartStore.cartReload > 0) {
      nextTick(() => {
        paging.value.reload();
      });
    }
  });
</script>

<style lang="scss" scoped>
  .header {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    display: flex;
    justify-content: space-between;
    background: white;
    z-index: 3;

    .header-btn {
      padding: 20rpx 32rpx 20rpx 10rpx;
      font-size: 30rpx;
    }
  }

  /* #ifdef H5 */
  .header {
    top: 84rpx;
  }
  /* #endif */

  .main {
    padding-top: 72rpx;

    .list {
      display: flex;
      height: calc(100vh - 185rpx);
      padding: 0 20rpx;
    }

    .goods-item {
      background: white;
      padding: 30rpx 22rpx 30rpx 22rpx;
      // margin-bottom: 100rpx;
      margin-bottom: 20rpx;
      border-radius: 20rpx;
      display: flex;
      align-items: start;
      &:first-child {
        margin-top: 24rpx;
      }

      .item-left {
        display: flex;
        align-items: center;

        .goods-logo {
          margin-left: 25rpx;
          margin-right: 20rpx;

          image {
            width: 150rpx;
            height: 150rpx;
            border-radius: 20rpx;
          }
        }
      }

      .item-right {
        flex: 1;

        .goods-name {
          font-size: 32rpx;
          font-weight: 600;
          display: inline-block;
          max-width: 445rpx;
          overflow: hidden;
          white-space: nowrap;
          text-overflow: ellipsis;
        }
        .desc-box {
          display: block;
        }
        .goods-desc {
          margin-top: 10rpx;
          font-size: 24rpx;
          color: #949494;
          background: #f5f5f5;
          padding: 5rpx 20rpx 5rpx 20rpx;
          border-radius: 10rpx;
        }

        .goods-bottom {
          margin-top: 20rpx;
          display: flex;
          align-items: center;
          justify-content: space-between;
        }

        .num-box {
          display: flex;
          align-items: center;
          border: 1px solid #dedede;
          border-radius: 50rpx;

          .minus-btn {
            padding: 12rpx 15rpx;
            border-right: 1px solid #dedede;
          }
          .plus-btn {
            padding: 12rpx 15rpx;
            border-left: 1px solid #dedede;
          }

          .goods-num {
            width: 55rpx;
            margin: 0 15rpx;
            font-size: 26rpx;
            text-align: center;
            // background: lightcoral;
          }
        }
      }
    }
  }

  .goods-price {
    font-size: 35rpx;
    font-weight: 600;
    color: #fe5303;

    &::before {
      content: '￥';
      font-size: 22rpx;
    }
  }

  .footer {
    position: fixed;
    width: 100%;
    bottom: 0;
    left: 0;
    align-items: center;
    justify-content: space-between;
    padding: 20rpx 30rpx 20rpx 20rpx;
    background: white;
    z-index: 2;

    .footer-left {
      display: flex;
      align-items: center;

      .total {
        margin-left: 40rpx;
        display: flex;
        align-items: center;
        font-size: 30rpx;

        .total-num {
          color: #5a5a5a;
          font-size: 24rpx;
          margin-left: 7rpx;
        }
      }
    }

    .action-btn {
      width: 200rpx;
      text-align: center;
      font-size: 30rpx;
      font-weight: 600;
      color: white;
      letter-spacing: 5rpx;
      padding: 22rpx 0;
      border-radius: 50rpx;
    }

    .settle {
      background-image: linear-gradient(to right, #fd8c02, #fe5303);
      box-shadow: rgba(226, 129, 2, 0.2) 0 5rpx 12rpx;
    }

    .delete {
      background-image: linear-gradient(to right, #f3204f, #f33720);
      box-shadow: rgba(255, 28, 0, 0.2) 0 5rpx 12rpx;
    }
  }

  /* #ifdef H5 */
  .footer {
    bottom: 96rpx;
  }
  /* #endif */
</style>
